/**
 * 基于_.js 进行扩展 基本上通用的代码，尽量扩展到这里面
 */
(function() {
	var utils={
			/**
			 * 格式化日期 如果什么都不传，默认配置当前 dateTime 日期或者日期数值 fmt 格式化的选择 默认 "yyyy-MM-dd
			 * hh:mm:ss"
			 */
			formatDate:function(dateTime,fmt) { // author: meizz
			var date = dateTime;
			if(!fmt) {
				fmt = "yyyy-MM-dd hh:mm:ss";
			}
			if(!date) {
				date = new Date();
			}
			if(typeof(dateTime) == 'number') { // 如果是数字 那么 进行转换
				date = new Date(date);
			}
			// 下面是开始替换
			var o = {
				"M+": date.getMonth() + 1, // 月份
				"d+": date.getDate(), // 日
				"h+": date.getHours(), // 小时
				"m+": date.getMinutes(), // 分
				"s+": date.getSeconds(), // 秒
				"q+": Math.floor((date.getMonth() + 3) / 3), // 季度
				"S": date.getMilliseconds() // 毫秒
			};
			if(/(y+)/.test(fmt))
				fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
			for(var k in o)
				if(new RegExp("(" + k + ")").test(fmt))
					fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
			return fmt;
		},
		/**
		 * 身份证号验证
		 */
			idNum:function (value) { 
			var AF={11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江",31:"上海",32:"江苏",33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外"};
			var AG = 0;
			var AH = value;
			AH = AH.toLowerCase().replace("x", "a");
			var AI = AH.length;
			var AJ="";
			if(AH != ""){
				if(AF[parseInt(AH.substr(0,2))]==null){
					$.fn.kvvalidate.errormessages["idnum"] = "地区不正确";
					return false;
				}
				if (AI==18){
					AJ=AH.substr(6,4)+"-"+Number(AH.substr(10,2))+"-"+Number(AH.substr(12,2));   
					var d = new Date(AJ.replace(/-/g,"/")); 
					if(AJ!=(d.getFullYear()+"-"+ (d.getMonth()+1) + "-" + d.getDate())){
						$.fn.kvvalidate.errormessages["idnum"] = "生日不正确";
						return false;
					}  
					for(var i = 17;i>=0;i--)   
						AG += (Math.pow(2,i) % 11) * parseInt(AH.charAt(17 - i),16);
					if(AG%11!=1){
						$.fn.kvvalidate.errormessages["idnum"] = "证件号不存在或输入错误";
						return false;
					};
				}else if (AI==15){   
					AJ = "19" + AH.substr(6,2) + "-" + Number(AH.substr(8,2)) + "-" + Number(AH.substr(10,2));
					var d = new Date(AJ.replace(/-/g,"/"));
					var dd = d.getFullYear().toString() + "-" + (d.getMonth()+1) + "-" + d.getDate();      
					if(AJ != dd){
						$.fn.kvvalidate.errormessages["idnum"] ="生日不正确";
						return false;
					};
				}else{
					$.fn.kvvalidate.errormessages["idnum"] ="长度不正确";
					return false;
				}	
			}
			return true;
			},	// 把数字金额转换为(中文大写)金额.
			convertCurrency:function(currencyDigits) { 
			    var MAXIMUM_NUMBER = 99999999999.99;
			    var CN_ZERO = "零";
			    var CN_ONE = "壹";
			    var CN_TWO = "贰";
			    var CN_THREE = "叁";
			    var CN_FOUR = "肆";
			    var CN_FIVE = "伍";
			    var CN_SIX = "陆";
			    var CN_SEVEN = "柒";
			    var CN_EIGHT = "捌";
			    var CN_NINE = "玖";
			    var CN_TEN = "拾";
			    var CN_HUNDRED = "佰";
			    var CN_THOUSAND = "仟";
			    var CN_TEN_THOUSAND = "万";
			    var CN_HUNDRED_MILLION = "亿";
			    var CN_DOLLAR = "元";
			    var CN_TEN_CENT = "角";
			    var CN_CENT = "分";
			    var CN_INTEGER = "整";

			    var integral;
			    var decimal;
			    var outputCharacters;
			    var parts;
			    var digits, radices, bigRadices, decimals;
			    var zeroCount;
			    var i, p, d;
			    var quotient, modulus;

			    // 验证是否为数字
			    if (currencyDigits.match(/[^,.\d]/) != null) {
			        alert("输入内容不能包含字符串!");
			        return "";
			    }

			    // 验证输入内容
			    if ((currencyDigits).match(/^(([1-9]{1}\d*)|([0]{1}))(\.(\d){1,2})?$/) == null) {
			        alert("输入内容不合法!");
			        return "";
			    }

			    currencyDigits = currencyDigits.replace(/,/g, "");
			    currencyDigits = currencyDigits.replace(/^0+/, "");

			    if (Number(currencyDigits) > MAXIMUM_NUMBER) {
			        alert("输入的数字过大!");
			        return "";
			    }

			    parts = currencyDigits.split(".");
			    if (parts.length > 1) {
			        integral = parts[0];
			        decimal = parts[1];

			        decimal = decimal.substr(0, 2);
			    } else {
			        integral = parts[0];
			        decimal = "";
			    }

			    digits = new Array(CN_ZERO, CN_ONE, CN_TWO, CN_THREE, CN_FOUR, CN_FIVE, CN_SIX, CN_SEVEN, CN_EIGHT, CN_NINE);
			    radices = new Array("", CN_TEN, CN_HUNDRED, CN_THOUSAND);
			    bigRadices = new Array("", CN_TEN_THOUSAND, CN_HUNDRED_MILLION);
			    decimals = new Array(CN_TEN_CENT, CN_CENT);

			    outputCharacters = "";

			    if (Number(integral) > 0) {
			        zeroCount = 0;
			        for (i = 0; i < integral.length; i++) {
			            p = integral.length - i - 1;
			            d = integral.substr(i, 1);
			            quotient = p / 4;
			            modulus = p % 4;
			            if (d == "0") {
			                zeroCount++;
			            } else {
			                if (zeroCount > 0) {
			                    outputCharacters += digits[0];
			                }
			                zeroCount = 0;
			                outputCharacters += digits[Number(d)] + radices[modulus];
			            }
			            if (modulus == 0 && zeroCount < 4) {
			                outputCharacters += bigRadices[quotient];
			            }
			        }
			        outputCharacters += CN_DOLLAR;
			    }

			    if (decimal != "") {
			        for (i = 0; i < decimal.length; i++) {
			            d = decimal.substr(i, 1);
			            if (d != "0") {
			                outputCharacters += digits[Number(d)] + decimals[i];
			            }
			        }
			    }

			    if (outputCharacters == "") {
			        outputCharacters = CN_ZERO + CN_DOLLAR;
			    }
			    if (decimal == "") {
			        outputCharacters += CN_INTEGER;
			    }
			    outputCharacters = outputCharacters;
			    return outputCharacters;
			},
		/**
		 * 比较两个时间的大小 startTime 大 返回false
		 * 
		 * @startTime 开始时间
		 * @endTime 结束时间
		 * @separator 分隔符 默认为-
		 */	 compareTime:function(startTime,endTime,separator){
				if(!separator){
					separator=/-/g;
				}
		      var begin=new Date(startTime.replace(separator,"/"));
		      var end=new Date(endTime.replace(separator,"/"));
		      // js判断日期
		      if(begin-end>0){
		         alert("开始日期要在截止日期之前!");  
		         return false;
		      }
		 },
		 /**
			 * 科学计数法
			 */
		 decimal:function(value){ 
				if (value) {  // 值未输入不走这个验证
					if(value.trim().length==0){ // 空字符不允许
						alert("不能够输入空字符");
						return false;
					}
					var longMin=-9223372036854775808;
					var longMax=9223372036854775807;
					// 判断值是否大于最大值或者小于最小值
					var newValue = new Decimal(value);
					if(newValue>longMax){ // 正数
						alert("数字不能大于"+longMin);
						return false;
					}
					if(newValue<longMin){ // 正数
						alert("数字不能小于"+longMax);
						return false;
					}
					return true;
				}else{
					alert("value非法"+value);
					return false;
				}
			},	
			/**
			 * obj 的key 和value 转变成 对象键值对 例如 ：obj={"key":"test","key2":"test2"}
			 * 调用之后变为
			 * arr=[{"name":"key","value":"test1"},{"name":"key2","value":"test2"}]
			 * 
			 * list的 name="",value=""
			 */
	    	objToArr:function(obj,name,value){
	    		if(!name){
	    			name="name";
	    		}
	    		if(!value){
	    			value="value";
	    		}
	    		var arr = new Array();
	    		for(var key in obj){
	    			var kvObj = {};
	    			kvObj[name]=key;
	    			kvObj[value]=obj[key];
	    			arr.push(kvObj);
	    		}
	    		return arr;
	    	},
	    	/**
	    	 * 根据配置项动态生成树
	    	 * options  配置 id 选项，配置name选项 ,配置子类数组
	    	 */
	    	listToTree:function (data,options){   //先实现功能，然后根据这个进行封装
	    		var defaultOptions={
	    				idName:"id",
	    				pidName:"pid",
	    				"childArrName":"childArr"
	    		}
	    		options = $.extend(options,defaultOptions); 
	    	    var cloneData = JSON.parse(JSON.stringify(data));    // 对源数据深度克隆
	    	    var tree = cloneData.filter((father)=>{              //循环所有项
	    	    	var branchArr = cloneData.filter((child)=>{
	    	            return father[options.idName] == child[options.pidName];      //返回每一项的子级数组
	    	        });
	    	        if(branchArr.length>0){
	    	            father[defaultOptions.childArrName] = branchArr;    //如果存在子级，则给父级添加一个childArr属性，并赋值
	    	        }
	    	        return father[options.pidName]==0;      //返回第一层
	    	    });
	    	    return tree;     //返回树形数据
	    	}
		};
	_.mixin(utils);
	
	
	//模拟js 通过字符串执行函数
	_.mixin({
		/**基于字符串获取 函数名称和参数对象 //不准持有无效的引号
		 * 示例  test(1,5,6,7);
		 * @params str  字符串函数
		 * 
		 */
		getFunctionObj: function(str) {

			var functionObj = {
				functionName: "",
				functionParams: []
			}
			if(_.isString(str)) {
				if(str.indexOf("(") != -1 && str.indexOf(")") != -1) {
					var arr = str.split("(");
					functionObj.functionName = arr[0];
					arr = arr[1].split(")");
					if(!_.isEmpty(arr[0])) {
						functionObj.functionParams = arr[0].split(",");
					}
				} else { //兼容未命名() 的函数
					functionObj.functionName = str;
				}
			}
			return functionObj;
		},
		/* 基于字符串获取当前window的对象函数对象
		 * @params str  字符串函数
		 * @parmas  falg   默认false,
		 * true 立即调用这个函数,false 返回函数对象及其函数参数
		 */
		getFunction: function(str, falg) {
			if(_.isString(str)) {
				var functionObj = _.getFunctionObj(str);
				var strFunction = functionObj.functionName;
				if(!_.isEmpty(strFunction)) {
					var arr = strFunction.split(".");
					strFunction = window[arr[0]];
					for(var i = 1, len = arr.length; i < len; i++) {
						if(!strFunction && !_.isFunction(strFunction) && !_.isObject(strFunction)) {
							return null;
						}
						strFunction = strFunction[arr[i]];
					}
					if(_.isFunction(strFunction)) {
						if(falg) {
							strFunction.apply(strFunction, functionObj.functionParams); //测试是否是方法可以测试出来
						}
						functionObj.fun = strFunction;
						return functionObj;
					}
				}
				return null;
			}
			return str;
		},
		exeFunction:function(functionObj){
			functionObj.fun.apply(functionObj.functionParams); //测试是否是方法可以测试出来
		}
	});

	
	
}.call(this));
